home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d13
/
port11.arc
/
PORT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-07
|
14KB
|
622 lines
/*
* Port - Do all kinds of wild and crazy things to PC I/O ports
*
* Rev 1.1 03/13/91
* John De Armond, Rapid Deployment Systems (jgd@dixie.com)
* Copyright 1991, John De Armond, Minimal Rights Reserved
*
* Compiled with the supplied project file under Borland C++ 2.0 but
* otherwise uncontaminated with C++ drool.
*
* Edited with MKS vi. To align indents, set tabstop=4, shiftwidth=4
*
* Surgeon General's warning: Caution: Misuse or abuse of this
* program is dangerous to the health of
* your hard disk, your memory, your video
* monitor and other such goodies. Govern
* your actions accordingly.
*/
#include <stdio.h>
#include <dos.h>
/***** define a few symbolic constants */
#define BYTE 1
#define WORD 2
#define HEX 3
#define DEC 4
#define IN 5
#define OUT 6
/***************************************/
unsigned int port=0, byte=0;
unsigned int save_port, save_byte;
char buf[80];
int entry_mode = HEX;
int byte_mode = BYTE;
int io_mode = OUT;
int quiet=0;
int match_byte;
extern char * token();
char *token_ptr;
int is_a_tty = 0;
int echo_command = 0;
main(argc,argv)
int argc;
char **argv;
{
unsigned int gak;
FILE *fp;
/* yes, I do mean "=" below */
if ( !(is_a_tty = isatty(0)) ) { /* check stdin for source */
echo_command=1; /* if we're on a pipe, echo each
command */
}
if (argc >= 2) { /* if only 2, then argv[1] is port number in hex */
sscanf(argv[1],"%x",&port);
}
if (argc >=3) { /* if 3 arguments, then argv[2] is the bit pattern*/
sscanf(argv[2],"%x",&byte);
}
printf("PORT v1.1 03/13/91 by John De Armond. (jgd@dixie.com)\n");
help();
for (;;) {
prompt();
/* this little trick allows us to redirect a file in and
then take keyboard input. This allows configuration files
to be piped in.
*/
if (fgets(buf,78,stdin) == NULL) { /* when we hit end of file, */
freopen("con", "r",stdin); /* open the console */
is_a_tty = 1;
echo_command=0;
continue;
}
if (echo_command) {
printf("cmd:%s",buf);
}
switch (buf[0]) {
case 'r': /* read port */
if (strlen(buf) >2) { /* we have a wait specification */
token(&buf[1]);
if (token_ptr != NULL) { /* if pattern specified */
sscanf(token_ptr,"%x",&match_byte);
printf(
"Waiting for byte %4.4x. Hit any key to terminate\n");
read_port();
while (!kbhit()) {
save_byte=byte;
read_port();
if (byte == match_byte) {
printf("Pattern %4.4x found, hit any key.\n",byte);
byte=save_byte;
break;
}
byte=save_byte;
} /* while */
getch(); /* clears the port */
} /* if token_ptr */
} else {
read_port();
}
break;
case 'w': /* write port */
if (strlen(buf) >2) { /* we have a wait specification */
token(&buf[1]);
if (token_ptr != NULL) { /* if pattern specified */
sscanf(token_ptr,"%x",&match_byte);
printf(
"Waiting for byte %4.4x. Hit any key to terminate\n",
match_byte);
write_port();
while (!kbhit()) {
save_byte=byte;
read_port();
if (byte == match_byte) {
printf("Pattern %4.4x found, hit any key.\n",byte);
byte=save_byte;
break;
}
byte=save_byte;
} /* while */
getch(); /* clears the port */
} /* if token_ptr */
} else {
write_port();
}
break;
case 'e': /* enter byte in default mode */
switch (buf[1]) {
case 'x': /* enter byte in hex mode*/
token(&buf[2]);
gak=0;
sscanf(token_ptr, "%x",&gak);
byte = gak;
entry_mode=HEX;
break;
case 'd': /* enter byte in decimal mode*/
token(&buf[2]);
gak=0;
sscanf(token_ptr, "%u",&gak);
byte = gak;
entry_mode=DEC;
break;
default: /* use the default mode */
token(&buf[2]);
gak=0;
if (entry_mode == HEX)
sscanf(token_ptr, "%x",&gak);
else
sscanf(token_ptr, "%u",&gak);
byte = gak;
break;
}
break;
case 't': /* toggle designated bit */
if (buf[1] == 'a') {
byte = ~ byte; /* special case, flip all bits */
break;
}
token(&buf[1]);
sscanf(token_ptr, "%d", &gak);
toggle_bit(gak);
break;
case 'i':
port++;
break;
case 'd':
port--;
break;
case 'm': /* set entry mode, hex, dec, byte, word */
switch (buf[1]) {
case 'x':
entry_mode = HEX;
break;
case 'd':
entry_mode = DEC;
break;
case 'b':
byte_mode = BYTE;
break;
case 'w':
byte_mode = WORD;
break;
case '\0': /* nothing entered */
default:
break;
}
break;
case 'c': /* clear all bits */
byte = 0;
break;
case 's': /* set all bits */
byte = ~0;
break;
case 'p': /* set port address */
token(&buf[1]);
if (entry_mode == HEX)
sscanf(token_ptr, "%x",&gak);
else
sscanf(token_ptr, "%u",&gak);
if (gak)
port = gak;
break;
case 'q': /* quit */
puts("");
exit(0);
case 'g': /* go continuously, repeat last I/O op */
switch (buf[1]) {
case 'i': /* input mode */
rep_io(IN);
break;
case 'o':
rep_io(OUT);
break;
default:
puts("Say What???");
break;
}
break;
case '<': /* get commands from a file */
token(&buf[1]);
if ( freopen(token_ptr,"r",stdin) == NULL ) {
printf("Cannot open file\n");
break; /* let the check at the head of the loop */
} /* reopen the console */
is_a_tty=0;
echo_command=1;
break;
case '?': /* show help */
help();
break;
default:
puts("Say What???");
} /* switch buf[0] */
print_it();
} /* for (;;) */
} /* main */
print_it()
{
int i,j;
unsigned int bit;
extern char * to_bin();
if (is_a_tty) {
printf(" Bits\n");
printf(" 5432 1098 7654 3210\n");
}
if (entry_mode == HEX) {
printf("Port: %4.4x Byte: %4.4x, %s ", port, byte, to_bin(byte));
printf("Mode= HEX ");
} else {
printf("Port: %5.5u Byte: %5.5u, %s ", port, byte, to_bin(byte));
printf("Mode= Decimal ");
}
if (byte_mode == BYTE) {
printf("Data= BYTE\n");
} else {
printf("Data= WORD\n");
}
}
/* convert an unsigned int to a binary string */
char *
to_bin(bit)
unsigned int bit;
{
static char string[25];
int i,j;
memset(string,0,25);
/* convert the byte to binary */
for (i=0,j=0; i<16; i++,j++) {
if ( bit & 0x01) {
string[18-j] = '1';
} else {
string[18-j] = '0';
}
if (!((i+1)%4) && i>1)
string[18- ++j] = ' ';
bit = bit >>1;
}
return (string);
}
prompt()
{
if (is_a_tty) {
printf("Command (help-?): ");
}
return;
}
read_port()
{
if (byte_mode == BYTE) {
byte = inportb(port);
} else {
byte = inport(port);
}
return;
}
write_port()
{
if (byte_mode == BYTE) {
outportb(port,byte);
} else {
outport(port,byte);
}
return;
}
help()
{
printf("\nUsage: port <port_address data> Arguments are in hex\n");
printf("\nCommands:\n");
printf(" \n");
printf("r read the port\n");
printf("w write the port\n");
printf("e<xd> Enter a byte (word in designated mode, hex or decimal)\n");
printf("m<xdbw> Mode (x=hex, d=dec, b=byte, w=word)\n");
printf("t n Toggle bit <n>\n");
printf("c Clear all bits\n");
printf("s Set all bits\n");
printf("p Set port address\n");
printf("g<io> Go In or Go Out - perform action continuously\n");
printf("i Increment port address one count\n");
printf("d Decrement port address one count\n");
printf("q Quit\n");
printf("< Redirect commands from a file\n");
printf("? Help\n\n");
printf("While in \"go out\" mode, keys 0-f will toggle bits, <t> will cause the output\n");
printf("to alternate between the byte pattern and all zeros.\n\n");
}
/****************************************************************************/
/* token takes a string passed in x and stores the next token in the global */
/* variable token_ptr. */
/* The function returns a pointer to the next character past the end of */
/* the token */
/****************************************************************************/
#define WHITESPACE 1
#define TOKEN 2
char *
token(x)
char *x;
{
int state = WHITESPACE;
static char *pointer;
pointer = (char *) NULL;
while (*x != (char) NULL) {
switch (*x) {
case ' ':
case '\x09': /* tab */
if (state == TOKEN) {
*x = '\x0'; /* null terminate */
token_ptr=pointer; /* point to beginning of this token */
return(++x);
} else {
++x; /* skip this character */
state = WHITESPACE;
}
break;
case '\n':
*x = '\x0'; /* null terminate return string */
token_ptr = pointer;
return((char *) 0);
default: /* this must be a token */
if (state == WHITESPACE) {
pointer=x++; /* set pointer to start of token */
state=TOKEN;
} else {
x++;
state=TOKEN;
}
break;
} /* switch */
} /* while */
if (state == TOKEN) {
*x = '\x0';
token_ptr = pointer;
return ( (char *) NULL);
} else {
token_ptr = (char *) NULL;
return ( (char *) NULL);
}
}
rep_io(x)
int x; /* mode, input or output */
{
unsigned int i;
char str[20];
int inp;
int toggle = 0;
unsigned int tmp_byte;
int old_byte;
int dirty;
toggle = 0;
i = 0;
old_byte=0;
dirty=0;
if (x == OUT) {
printf(
"\nContinuous output - Press keys 0-f to toggle bits, <t> to toggle between\n");
printf("output byte and 0000. Hit <enter> to stop. ");
} else {
printf("\nContinuous input - hit <enter> to stop. ");
}
printf("\"<\" and \">\" changes port address\n");
printf("Hit any other key to update screen.\n\n");
if (entry_mode == HEX) {
sprintf(str,"%4.4x",port);
} else {
sprintf(str,"%5.5u",port);
}
printf("Port = %s\n", str);
showit(x,i,toggle);
for ( ;; ) {
if (kbhit() ) { /* if keyboard input, process to toggle bits */
inp = getch();
switch (inp) {
case '\n':
case '\r':
puts(" ");
return;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (x == OUT)
toggle_bit(inp-'0');
dirty = ~dirty;
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
if (x == OUT)
toggle_bit(inp - 'a' + 10);
dirty = ~dirty;
break;
case 't': /* toggle between outputing byte and 0000 */
if (x == OUT) {
toggle = ~toggle;
showit(x,i,toggle);
}
break;
case '<':
port--;
if (entry_mode == HEX) {
sprintf(str,"%4.4x",port);
} else {
sprintf(str,"%5.5u",port);
}
printf(" Port = %s\n", str);
showit(x,i,toggle);
break;
case '>':
port++;
if (entry_mode == HEX) {
sprintf(str,"%4.4x",port);
} else {
sprintf(str,"%5.5u",port);
}
printf(" Port = %s\n", str);
showit(x,i,toggle);
break;
default: /* any other key updates the screen */
showit(x,i,toggle);
break;
}
} /* if */
/* actually do the port thang */
if (x == IN) {
old_byte = byte;
read_port();
if (old_byte != byte)
showit(x,i,toggle);
} else { /* output mode */
if (dirty) {
dirty = ~dirty;
showit(x,i,toggle);
}
/* if toggle specified, then alternate between the byte and
all 0000 */
if (toggle) {
if (i%2) {
tmp_byte = byte;
byte = 0;
write_port();
byte = tmp_byte;
} else {
write_port();
}
} else { /* if not toggle */
write_port();
}
}
i++;
}
}
/* this routine toggles a specified bit in the global variable byte */
toggle_bit(x)
{
unsigned int bits[] = {
0x01,
0x02,
0x04,
0x08,
0x10,
0x20,
0x40,
0x80,
0x100,
0x200,
0x400,
0x800,
0x1000,
0x2000,
0x4000,
0x8000,
};
byte = byte ^ bits[x%16];
return;
}
/* update screen during continuous output or input */
showit(x,i,toggle)
int x;
int i;
int toggle;
{
extern char * to_bin();
if (x == IN) {
if (entry_mode == HEX) {
printf("\rRead loop:%5.5u, value = %4.4x, %s", i,byte,to_bin(byte));
} else {
printf("\rRead loop:%5.5u, value = %5.5u, %s", i,byte,to_bin(byte));
}
} else {
if (entry_mode == HEX) {
printf("\rWrite loop:%5.5u, value = %4.4x, %s", i,byte,to_bin(byte));
} else {
printf("\rWrite loop:%5.5u, value = %5.5u, %s", i,byte,to_bin(byte));
}
if (toggle) {
printf(" toggling");
} else {
printf(" ");
}
}
return;
}
/************************** end of file **********************************/